// 视频签到页面 - 实时视频流传输
import { baseUrl } from "../../api/api";
Page({
    data: {
        teacherId: '',
        checkinId: '',
        isInitialized: false,
        isStreaming: false, // 是否正在推流
        statusText: '准备开始视频签到...',
        errorMessage: '',
        frameRate: 10, // 控制发送帧率
        imageFormat: 'jpeg', // 图片格式
        imageQuality: 0.8 // 图片质量(0-1)
    },

    // 页面加载
    onLoad: function(options) {
        // 获取参数
        const { id } = options;
        if (!id) {
            this.showError('签到ID不能为空');
            return;
        }

        // 获取用户信息
        const userInfo = wx.getStorageSync('userInfo');
        if (!userInfo || !userInfo.userId) {
            this.showError('未获取到用户信息');
            return;
        }

        this.setData({
            checkinId: id,
            teacherId: userInfo.userId
        });

        // 获取摄像头权限
        wx.authorize({
            scope: "scope.camera",
            success: () => {
                // 授权成功
                console.log("摄像头授权成功");
                this.initCamera();
            },
            fail: () => {
                wx.showToast({
                    title: "请授权摄像头权限",
                    icon: "none",
                    duration: 2000,
                });
            },
        });
    },

    // 页面卸载
    onUnload: function() {
        this.stopStreaming();
    },

    // 初始化摄像头
    initCamera: function() {
        this.setData({ statusText: '正在初始化摄像头...' });

        try {
            // 创建摄像头上下文
            this.ctx = wx.createCameraContext();

            // 设置为已初始化
            this.setData({
                isInitialized: true,
                statusText: '摄像头已准备就绪，可以开始视频签到'
            });
        } catch (error) {
            console.error('摄像头初始化错误:', error);
            this.showError('摄像头初始化失败');
        }
    },

    // 处理相机错误
    cameraError: function(e) {
        console.error('相机错误:', e.detail);
        this.showError(`相机错误: ${e.detail.errMsg}`);
    },

    // 开始视频流推送
    startStreaming: function() {
        if (!this.ctx || this.data.isStreaming) return;

        this.setData({ isStreaming: true, statusText: '正在准备视频流...' });

        // 连接WebSocket
        this.connectWebSocket();
    },

    // 停止视频流推送
    stopStreaming: function() {
        if (!this.ctx || !this.data.isStreaming) return;

        // 停止帧捕获
        if (this.cameraListener) {
            this.cameraListener.stop();
            this.cameraListener = null;
        }

        this.setData({
            isStreaming: false,
            statusText: '已停止视频流推送'
        });

        // 关闭WebSocket连接
        this.closeWebSocket();
    },

    // 连接WebSocket
    connectWebSocket: function() {
        const wsUrl = `${baseUrl.replace("http","ws")}/ws/video-stream/${this.data.teacherId}/${this.data.checkinId}`;

        // 重置重连次数
        this.reconnectAttempts = 0;

        try {
            this.socket = wx.connectSocket({
                url: wsUrl,
                success: () => {
                    console.log("WebSocket连接请求已发送");
                },
                fail: (err) => {
                    console.error("WebSocket连接请求失败:", err);
                    this.showError("连接服务器失败: " + err.errMsg);
                    this.setData({ isStreaming: false });
                },
            });

            // 监听WebSocket连接打开事件
            this.socket.onOpen(() => {
                console.log("WebSocket连接已打开");

                // 发送连接消息
                this.sendWebSocketMessage("CONNECTED");

                // 开始捕获摄像头画面
                this.startCameraCapture();

                this.setData({
                    statusText: "已连接服务器，正在推送视频流...",
                });
            });

            // 监听WebSocket错误事件
            this.socket.onError((err) => {
                console.error("WebSocket错误:", err);
                this.showError("WebSocket连接错误");
                this.setData({ isStreaming: false });
            });

            // 监听WebSocket关闭事件
            this.socket.onClose((event) => {
                console.log("WebSocket连接已关闭:", event);

                // 如果是正在推流状态，尝试重连
                if (this.data.isStreaming) {
                    this.tryReconnect();
                }
            });

            // 监听WebSocket消息
            this.socket.onMessage((res) => {
                console.log("收到服务器消息:", res.data);
                // 处理服务器消息
            });
        } catch (error) {
            console.error("创建WebSocket连接出错:", error);
            this.showError("连接服务器出错");
            this.setData({ isStreaming: false });
        }
    },

    // 尝试重新连接
    tryReconnect: function() {
        const maxReconnectAttempts = 3;

        if (!this.reconnectAttempts) {
            this.reconnectAttempts = 0;
        }

        if (this.reconnectAttempts < maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`尝试重新连接 (${this.reconnectAttempts}/${maxReconnectAttempts})...`);
            this.setData({
                statusText: `连接已断开，正在尝试重连(${this.reconnectAttempts}/${maxReconnectAttempts})...`
            });

            setTimeout(() => {
                if (this.data.isStreaming) {
                    this.connectWebSocket();
                }
            }, 2000 * this.reconnectAttempts);
        } else {
            this.setData({
                isStreaming: false,
                statusText: '连接已断开，重连失败'
            });
            this.showError('与服务器连接断开，请重试');
        }
    },

    // 开始摄像头捕获
    startCameraCapture: function() {
        try {
            // 发送开始流传输消息
            this.sendWebSocketMessage('START_STREAMING');

            // 开始帧捕获
            this.frameCount = 0;
            this.lastFrameTime = 0;

            // 使用摄像头帧监听
            this.cameraListener = this.ctx.onCameraFrame((frame) => {
                // 控制帧率，避免发送太多数据
                const now = Date.now();
                if (now - this.lastFrameTime < 1000 / this.data.frameRate) {
                    return;
                }

                this.lastFrameTime = now;
                this.frameCount++;

                // 每10帧发送一次状态更新
                if (this.frameCount % 10 === 0) {
                    console.log(`已发送 ${this.frameCount} 帧画面`);
                }

                // 处理并发送帧数据
                this.processAndSendFrame(frame);
            });

            // 启动监听
            this.cameraListener.start();
            console.log('开始摄像头捕获');
        } catch (error) {
            console.error('启动摄像头捕获失败:', error);
            this.showError('启动视频流失败');
            this.setData({ isStreaming: false });
        }
    },

    // 处理并发送视频帧
    processAndSendFrame: function(frame) {
        if (!this.socket || !this.data.isStreaming) return;

        try {
            // 创建一个临时Canvas用于处理图像
            const canvas = wx.createOffscreenCanvas({ type: '2d', width: frame.width, height: frame.height });
            const ctx = canvas.getContext('2d');

            // 创建图像数据
            const imgData = ctx.createImageData(frame.width, frame.height);
            // 复制帧数据
            imgData.data.set(new Uint8ClampedArray(frame.data));
            // 将图像数据绘制到Canvas
            ctx.putImageData(imgData, 0, 0);

            // 将Canvas转为Base64图片
            const base64 = canvas.toDataURL(`image/${this.data.imageFormat}`, this.data.imageQuality);

            // 创建帧数据对象
            const frameData = {
                width: frame.width,
                height: frame.height,
                timestamp: Date.now(),
                format: this.data.imageFormat,
                data: base64
            };

            // 发送帧数据
            this.sendWebSocketMessage(JSON.stringify(frameData));
        } catch (error) {
            console.error('处理视频帧失败:', error);
        }
    },

    // 发送WebSocket消息
    sendWebSocketMessage: function(message) {
        if (!this.socket) return;

        this.socket.send({
            data: message,
            fail: (err) => {
                console.error('发送WebSocket消息失败:', err);
            }
        });
    },

    // 关闭WebSocket连接
    closeWebSocket: function() {
        if (this.socket) {
            // 发送结束消息
            this.sendWebSocketMessage('DISCONNECTED');

            // 延迟关闭连接，确保消息发送
            setTimeout(() => {
                this.socket.close({
                    success: () => {
                        console.log('WebSocket已关闭');
                    },
                    fail: (err) => {
                        console.error('关闭WebSocket失败:', err);
                    }
                });
            }, 300);
        }
    },

    // 显示错误信息
    showError: function(message) {
        this.setData({ errorMessage: message });
        wx.showToast({
            title: message,
            icon: 'none',
            duration: 2000
        });
    },

    // 返回上一页
    goBack: function() {
        wx.navigateBack();
    }
});